package com.onlyxiahui.common.action.description.util;

import java.lang.reflect.Field;

/**
 * 
 * Date 2019-03-30 17:16:59<br>
 * Description 反射工具
 * 
 * @author XiaHui<br>
 * @since 1.0.0
 */
public class ActionReflectUtil {

	/**
	 * 
	 * Date 2019-03-30 17:11:57<br>
	 * Description 深度查找Class的属性Field,当前class没找到就继续找父类
	 * 
	 * @param clazz
	 * @param rootClass :为设定最顶层的父类，找到此类就不继续了，默认为Object
	 * @param name
	 * @return Field
	 * @since 1.0.0
	 */
	public static Field getField(Class<?> clazz, Class<?> rootClass, String name) {
		Field field = getField(clazz, name);
		// 如果字段不存在，并且顶层rootClass不等于当前
		if (null == field && clazz != rootClass) {
			Class<?> superClass = clazz.getSuperclass();
			field = getField(superClass, name);
			boolean isRoot = superClass == rootClass;

			while (!isRoot && null == field) {
				superClass = superClass.getSuperclass();
				field = getField(superClass, name);
				isRoot = superClass == rootClass;
			}
		}
		return field;
	}

	/**
	 * 
	 * Date 2019-03-30 17:13:01<br>
	 * Description 获取class中的字段
	 * 
	 * @param clazz
	 * @param name
	 * @return Field
	 * @since 1.0.0
	 */
	public static Field getField(Class<?> clazz, String name) {
		if (null != clazz && null != name) {
			Field[] fields = clazz.getDeclaredFields();
			String internedName = name.intern();
			for (int i = 0; i < fields.length; i++) {
				if (null != fields[i] && fields[i].getName() == internedName) {
					return fields[i];
				}
			}
		}
		return null;
	}

	/**
	 * 获取属性的值
	 * 
	 * @author XiaHui [onlovexiahui@qq.com] Date 2019/04/18 12:00
	 * @param data
	 * @param field
	 * @return Object
	 */
	public static Object getValue(Object data, Field field) {
		Object value = null;
		if (null != field) {
			// 使对象的属性可访问
			try {
				boolean isAccessible = field.isAccessible();
				if (!isAccessible) {
					field.setAccessible(true);
				}
				value = field.get(data);
				if (!isAccessible) {
					field.setAccessible(isAccessible);
				}
			} catch (IllegalArgumentException | IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return value;
	}

	/**
	 * 
	 * Date 2019-03-30 17:16:00<br>
	 * Description 获取data对象fieldName的Field
	 * 
	 * @param data
	 * @param fieldName
	 * @return Field
	 * @since 1.0.0
	 */
	public static Field getFieldByName(Object data, String fieldName) {
		Field field = getField(data.getClass(), fieldName);
		return field;
	}

	/**
	 * 
	 * Date 2019-03-30 17:16:19<br>
	 * Description 获取data对象fieldName的属性值
	 * 
	 * @param data
	 * @param fieldName
	 * @return Object
	 * @since 1.0.0
	 */
	public static Object getValueByFieldName(Object data, String fieldName) {
		Field field = getFieldByName(data, fieldName);
		Object value = null;
		if (field != null) {
			try {
				if (field.isAccessible()) {
					value = field.get(data);
				} else {
					field.setAccessible(true);
					value = field.get(data);
					field.setAccessible(false);
				}
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return value;
	}

	/**
	 * 
	 * Date 2019-03-30 17:16:42<br>
	 * Description 设置data对象fieldName的属性值
	 * 
	 * @param data
	 * @param fieldName
	 * @param value
	 * @since 1.0.0
	 */
	public static void setValueByFieldName(Object data, String fieldName, Object value) {
		try {
			Field field = getFieldByName(data, fieldName);
			if (field.isAccessible()) {
				field.set(data, value);
			} else {
				field.setAccessible(true);
				field.set(data, value);
				field.setAccessible(false);
			}
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
	}
}
